home *** CD-ROM | disk | FTP | other *** search
- /* IP interface control and configuration routines
- * Copyright 1991 Phil Karn, KA9Q
- *
- * Mods by PA0GRI
- */
- #include "global.h"
- #include "ctype.h"
- #include "commands.h"
- #include "mbuf.h"
- #include "proc.h"
- #ifndef MSDOS
- #include "iface.h"
- #endif
- #ifdef ETHER
- #include "enet.h"
- #endif
- #include "arp.h"
- #include "pktdrvr.h"
- #include "nr4.h"
- #include "mailbox.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: iface.c,v 1.25 1997/09/07 00:31:16 root Exp root $";
- #endif
-
- #ifdef NETROM
- extern struct iface *Nr_iface;
- extern char Nralias[];
- #endif
-
- static void showiface (struct iface * ifp);
- static int ifipaddr (int argc, char *argv[], void *p);
- static int ifipcall (int argc, char *argv[], void *p);
- static int iflinkadr (int argc, char *argv[], void *p);
- static int ifbroad (int argc, char *argv[], void *p);
- static int ifnetmsk (int argc, char *argv[], void *p);
- static int ifmtu (int argc, char *argv[], void *p);
- static int ifmetric (int argc, char *argv[], void *p);
- static int ifforw (int argc, char *argv[], void *p);
- static int ifencap (int argc, char *argv[], void *p);
- static int ifdescr (int argc, char *argv[], void *p);
-
- #ifdef RXECHO
- static int ifrxecho (int argc, char *argv[], void *p);
- #endif
-
-
- static const char subcommands[] = "valid subcommands:\n";
- static const char nochangeIP[] = "Cannot change IP address !\n";
- static const char setIPcall[] = "Can't set IP call\n";
- static const char setlinkaddr[] = "Can't set link address\n";
- static const char encaperr[] = "Encapsulation mode '%s' unknown\n";
- static const char notsametype[] = "'%s not the same type!\n";
- static const char showfmt[] = "%-10s IP addr %s MTU %u Metric %d Link encap ";
- static const char notset[] = "not set\n";
- static const char showlink[] = " Link addr %s";
- static const char showsent[] = " sent: ip %lu tot %lu idle %s\n";
- static const char showrecv[] = " recv: ip %lu tot %lu idle %s\n";
- static const char showdescr[] = " descr: %s";
- static const char detnope[] = "Can't detach loopback or encap interface\n";
- static const char showflags[] = " flags 0x%lx trace 0x%x netmask 0x%08lx broadcast %s\n";
- static const char showforw[] = " output forward to %s\n";
-
- #ifdef AX25
- static const char showIPcall[] = " IP call %s";
- static const char showlenirtt[] = " Paclen %d Irtt %lu\n";
- static const char showbctext[] = " BCText: %s\n";
- static const char showremote[] = " Remote call %s";
- #ifdef AXIP
- static const char showremoteIP[] = " Remote IP addr %s\n";
- #endif
- #endif
-
- #ifdef RXECHO
- static const char showrxecho[] = " rx packets echoed to %s\n";
- #endif
-
-
-
- struct iftcp def_iftcp = {DEF_RTT, 0L, DEF_WND, DEF_MSS, 31, DEF_RETRIES, 0, 0};
-
- /* Interface list header */
- struct iface *Ifaces = &Loopback;
-
- #ifdef AXIP
- extern uint32 *axipaddr; /* table of IP addresses of AX.25 interfaces */
- #endif
-
-
- /* Loopback pseudo-interface */
- struct iface Loopback =
- {
- #ifdef ENCAP
- &Encap, /* Link to next entry */
- #else
- NULLIF,
- #endif
- "loopback", /* name */
- NULLCHAR, /* description */
- 0x7f000001UL, /* addr 127.0.0.1 */
- 0xffffffffUL, /* broadcast 255.255.255.255 */
- 0xffffffffUL, /* netmask 255.255.255.255 */
- MAXINT16, /* mtu No limit */
- 1, /* metric */
- 0, /* flags */
- #ifdef NETROM
- 0, /* quality */
- #endif
- 0, /* trace */
- NULLCHAR, /* trfile */
- NULLFILE, /* trfp */
- -1, /* trsock */
- NULLIF, /* forw */
- #ifdef RXECHO
- NULLIF, /* rxecho */
- #endif
- NULLPROC, /* rxproc */
- NULLPROC, /* txproc */
- NULLPROC, /* supv */
- 0, /* dev */
- (int32 (*)(struct iface *, int, int, int32)) 0,
- NULLFP ((struct iface *, int, int32)), /* (*iostatus) */
- NULLFP ((struct iface *)), /* (*stop) */
- NULLCHAR, /* hwaddr */
- NULLCHAR, /* ipcall */
- NULLCHAR, /* rmtaddr */
- #ifdef AX25
- NULL, /* ax25 protocol data */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- /* ax25 counters */
- #endif /* AX25 */
- &def_iftcp, /* tcp protocol data */
- NULL, /* extension */
- CL_NONE, /* type */
- 0, /* xdev */
- 0, /* port */
- &Iftypes[0], /* iftype */
- NULLFP ((struct mbuf *, struct iface *, uint32, int, int, int, int)), /* (*send) */
- NULLFP ((struct iface *, const char *, char *, int16, struct mbuf *)), /* (*output) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*raw) */
- NULLVFP ((struct iface *)), /* (*show) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*discard) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*echo) */
- 0, /* ipsndcnt */
- 0, /* rawsndcnt */
- 0, /* iprecvcnt */
- 0, /* rawrcvcnt */
- 0, /* lastsent */
- 0, /* lastrecv */
- };
-
-
-
- #ifdef ENCAP
- /* Encapsulation pseudo-interface */
- struct iface Encap =
- {
- NULLIF,
- "encap", /* name */
- NULLCHAR, /* description */
- INADDR_ANY, /* addr 0.0.0.0 */
- 0xffffffffUL, /* broadcast 255.255.255.255 */
- 0xffffffffUL, /* netmask 255.255.255.255 */
- MAXINT16, /* mtu No limit */
- 1, /* metric */
- 0, /* flags */
- #ifdef NETROM
- 0, /* quality */
- #endif
- 0, /* trace */
- NULLCHAR, /* trfile */
- NULLFILE, /* trfp */
- -1, /* trsock */
- NULLIF, /* forw */
- #ifdef RXECHO
- NULLIF, /* rxecho */
- #endif
- NULLPROC, /* rxproc */
- NULLPROC, /* txproc */
- NULLPROC, /* supv */
- 0, /* dev */
- (int32 (*)(struct iface *, int, int, int32)) 0, /* (*ioctl) */
- NULLFP ((struct iface *, int, int32)), /* (*iostatus) */
- NULLFP ((struct iface *)), /* (*stop) */
- NULLCHAR, /* hwaddr */
- NULLCHAR, /* ipcall */
- NULLCHAR, /* rmtaddr */
- #ifdef AX25
- NULL, /* ax25 protocol data */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- /* ax25 counters */
- #endif /* AX25 */
- &def_iftcp, /* tcp protocol data */
- NULL, /* extension */
- CL_NONE, /* type */
- 0, /* xdev */
- 0, /* port */
- &Iftypes[0], /* iftype */
- ip_encap, /* (*send) */
- NULLFP ((struct iface *, const char *, char *, int16, struct mbuf *)), /* (*output) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*raw) */
- NULLVFP ((struct iface *)), /* (*show) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*discard) */
- NULLFP ((struct iface *, struct mbuf *)), /* (*echo) */
- 0, /* ipsndcnt */
- 0, /* rawsndcnt */
- 0, /* iprecvcnt */
- 0, /* rawrcvcnt */
- 0, /* lastsent */
- 0, /* lastrecv */
- };
-
- #endif /*ENCAP*/
-
-
-
- #if defined(DRSI) || defined(EAGLE) || defined(PC_EC) || defined(HAPN) || defined(PC100)
- char Noipaddr[] = "IP address field missing, and ip address not set\n";
- #endif
-
- static struct cmds Ifcmds[] =
- {
- #ifdef AX25
- { "ax25", ifax25, 0, 0, NULLCHAR },
- #endif
- { "broadcast", ifbroad, 0, 2, NULLCHAR },
- { "description", ifdescr, 0, 0, NULLCHAR },
- { "encapsulation", ifencap, 0, 2, NULLCHAR },
- { "forward", ifforw, 0, 2, NULLCHAR },
- { "ipaddress", ifipaddr, 0, 2, NULLCHAR },
- { "ipcall", ifipcall, 0, 2, NULLCHAR },
- { "linkaddress", iflinkadr, 0, 2, NULLCHAR },
- { "metric", ifmetric, 0, 2, NULLCHAR },
- { "mtu", ifmtu, 0, 2, NULLCHAR },
- { "netmask", ifnetmsk, 0, 2, NULLCHAR },
- #ifdef RXECHO
- { "rxecho", ifrxecho, 0, 2, NULLCHAR },
- #endif
- { "tcp", doiftcp, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
-
- /* Set interface parameters */
- int
- doifconfig (int argc, char *argv[], void *p OPTIONAL)
- {
- struct iface *ifp;
- int i, step = 2, newargc = argc;
-
- if (argc < 2) {
- for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- showiface (ifp);
- return 0;
- }
- if ((ifp = if_lookup (argv[1])) == NULLIF) {
- tprintf (Badinterface, argv[1]);
- return 1;
- }
- if (argc == 2) {
- showiface (ifp);
- if (ifp->show != NULLVFP ((struct iface *)))
- (*ifp->show) (ifp);
- return 0;
- }
- if (argc == 3) {
- dohelper (subcommands, Ifcmds, NULLCHAR, NULLCHAR, NULLCHAR);
- return 1;
- }
- for (i = 2; i < argc - 1; i += step) {
- step = (tolower (argv[i][0]) == 't') ? 3 : 2;
- (void) subcmd (Ifcmds, newargc - 1, &argv[i - 1], ifp);
- newargc -= step;
- }
- return 0;
- }
-
-
-
- /* Remove iface tracing to the current output socket */
- void
- removetrace ()
- {
- struct iface *ifp;
-
- for (ifp = Ifaces; ifp; ifp = ifp->next)
- if (ifp->trsock == Curproc->output) {
- ifp->trace = 0;
- /* We have to close the socket, because usesock() was called !*/
- close_s (ifp->trsock);
- ifp->trsock = -1;
- }
- }
-
-
-
- static int
- ishexaddr (char *str)
- {
- int k;
- int l = (int) strlen (str);
-
- if (l < 8 || l > 10)
- return 0;
- if (!strncasecmp (str, "0x", 2))
- return 1;
- for (k = 0; k < 8; k++) {
- if (!isxdigit (str[k]))
- return 0;
- }
- return 1;
- }
-
-
- /* Set interface IP address */
- static int
- ifipaddr (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- /* Do not allow loopback iface to be changed ! - WG7J */
- if (ifp == &Loopback) {
- tputs (nochangeIP);
- return 0;
- }
- ifp->addr = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]) : resolve (argv[1]);
- return 0;
- }
-
-
-
- /* Set IP call sign */
- static int
- ifipcall (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- if (ifp->iftype == NULLIFT || ifp->iftype->scan == NULL) {
- tputs (setIPcall);
- return 1;
- }
- if (ifp->ipcall != NULLCHAR)
- free (ifp->ipcall);
- ifp->ipcall = mallocw ((unsigned) ifp->iftype->hwalen);
- (void) (*ifp->iftype->scan) (ifp->ipcall, argv[1]);
- return 0;
- }
-
-
-
- /* Set link (hardware) address */
- static int
- iflinkadr (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- if (ifp->iftype == NULLIFT || ifp->iftype->scan == NULL) {
- tputs (setlinkaddr);
- return 1;
- }
- if (ifp->hwaddr != NULLCHAR)
- free (ifp->hwaddr);
- ifp->hwaddr = mallocw ((unsigned) ifp->iftype->hwalen);
- (void) (*ifp->iftype->scan) (ifp->hwaddr, argv[1]);
- #if defined(MAILBOX) && defined(NETROM)
- if (ifp == Nr_iface) /*the netrom call just got changed! - WG7J*/
- setmbnrid ();
- #endif
- return 0;
- }
-
-
-
- /* Set interface broadcast address. This is actually done
- * by installing a private entry in the routing table.
- */
- static int
- ifbroad (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
- struct route *rp;
-
- rp = rt_blookup (ifp->broadcast, 32);
- if (rp != NULLROUTE && rp->iface == ifp)
- (void) rt_drop (ifp->broadcast, 32);
-
- ifp->broadcast = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]): resolve (argv[1]);
- (void) rt_add (ifp->broadcast, 32, 0L, ifp, 1L, 0L, 1);
- return 0;
- }
-
-
-
- /* Set the network mask. This is actually done by installing
- * a routing entry.
- */
- static int
- ifnetmsk (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
- struct route *rp;
-
- /* Remove old entry if it exists */
- rp = rt_blookup (ifp->addr & ifp->netmask, (unsigned) mask2width (ifp->netmask));
- if (rp != NULLROUTE)
- (void) rt_drop (rp->target, rp->bits);
-
- ifp->netmask = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]) : resolve (argv[1]);
- (void) rt_add (ifp->addr, (unsigned) mask2width (ifp->netmask), 0L, ifp, 0L, 0L, 0);
- return 0;
- }
-
-
-
- /* Command to set interface encapsulation mode */
- static int
- ifencap (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- if (setencap (ifp, argv[1]) != 0) {
- tprintf (encaperr, argv[1]);
- return 1;
- }
- return 0;
- }
-
-
-
- /* Function to set encapsulation mode */
- int
- setencap (struct iface *ifp, const char *mode)
- {
- struct iftype *ift = (struct iftype *) 0;
-
- if (mode != NULL) {
- /* Configure the whole interface */
- for (ift = &Iftypes[0]; ift->name != NULLCHAR; ift++)
- if (strnicmp (ift->name, mode, strlen (mode)) == 0)
- break;
- if (ift->name == NULLCHAR)
- return -1;
-
- ifp->iftype = ift;
- ifp->send = ift->send;
- ifp->output = ift->output;
- ifp->type = ift->type;
- }
- /* Set the tcp and ax25 interface parameters */
- if (!ifp->tcp)
- ifp->tcp = callocw (1, sizeof (struct iftcp));
-
- init_iftcp (ifp->tcp);
- #ifdef AX25
- if (ift && ift->type == CL_AX25) {
- if (!ifp->ax25)
- ifp->ax25 = callocw (1, sizeof (struct ifax25));
-
- init_ifax25 (ifp->ax25);
- ifp->flags |= AX25_BEACON + MAIL_BEACON + AX25_DIGI + LOG_AXHEARD + LOG_IPHEARD;
- }
- #endif
- return 0;
- }
-
-
-
- #ifdef RXECHO
- /* Set interface IP address */
- static int
- ifrxecho (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
- struct iface *rxecho;
-
- if (!stricmp ("off", argv[1])) {
- ifp->rxecho = NULLIF;
- return 0;
- };
- if ((rxecho = if_lookup (argv[1])) == NULL) {
- tprintf (Badinterface, argv[1]);
- return 0;
- };
- if (ifp->type != rxecho->type) {
- tprintf (notsametype, argv[1]);
- return 0;
- };
- ifp->rxecho = rxecho;
- return 0;
- }
- #endif /* RXECHO */
-
-
-
- /* Set interface Maximum Transmission Unit */
- static int
- ifmtu (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- ifp->mtu = (int16) atoi (argv[1]);
- #ifdef NETROM
- /* Make sure NETROM mtu <= 236 ! - WG7J */
- if (ifp == Nr_iface)
- if (Nr_iface->mtu > NR4MAXINFO)
- Nr_iface->mtu = NR4MAXINFO;
- #endif
- return 0;
- }
-
-
-
- /* Set interface metric for RIP - */
- static int
- ifmetric (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- ifp->iface_metric = atoi (argv[1]);
- return 0;
- }
-
-
-
- /* Set interface forwarding */
- static int
- ifforw (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- ifp->forw = if_lookup (argv[1]);
- if (ifp->forw == ifp)
- ifp->forw = NULLIF;
- return 0;
- }
-
-
-
- /*give a little description for each interface - WG7J*/
- static int
- ifdescr (int argc OPTIONAL, char *argv[], void *p)
- {
- struct iface *ifp = p;
-
- #ifdef NETROM
- #ifdef ENCAP
- if ((ifp == &Loopback) || (ifp == &Encap) || (ifp == Nr_iface))
- #else
- if ((ifp == &Loopback) || (ifp == Nr_iface))
- #endif /*ENCAP*/
- #else /*NETROM*/
- #ifdef ENCAP
- if ((ifp == &Loopback) || (ifp == &Encap))
- #else
- if (ifp == &Loopback)
- #endif /*ENCAP*/
- #endif /*NETROM*/
- return 0;
-
- if (ifp->descr != NULLCHAR) {
- free (ifp->descr);
- ifp->descr = NULLCHAR; /* reset the pointer */
- }
- if (!strlen (argv[1]))
- return 0; /* clearing the buffer */
-
- ifp->descr = mallocw (strlen (argv[1]) + 2); /* allow for the EOL char etc */
- strcpy (ifp->descr, argv[1]);
- strcat (ifp->descr, "\n"); /* add the EOL char */
-
- return 0;
- }
-
-
-
- /* Display the parameters for a specified interface */
- static void
- showiface (register struct iface *ifp)
- {
- char tmp[25];
-
- tprintf (showfmt, ifp->name, inet_ntoa (ifp->addr), (int) ifp->mtu, ifp->iface_metric);
- if (ifp->iftype == NULLIFT)
- tputs (notset);
- else {
- tprintf ("%s%s\n", ifp->iftype->name, (ifp->rmtaddr != NULLCHAR) ? " (AXIP)" : "");
- if (ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR) {
- tprintf (showlink, (*ifp->iftype->format) (tmp, ifp->hwaddr));
- #ifdef AX25
- if (ifp->iftype->type == CL_AX25) {
- if (ifp->ipcall != NULLCHAR)
- tprintf (showIPcall, (*ifp->iftype->format) (tmp, ifp->ipcall));
- tprintf (showlenirtt, (int) ifp->ax25->paclen, ifp->ax25->irtt);
- if (ifp->ax25->bctext)
- tprintf (showbctext, ifp->ax25->bctext);
- if (ifp->rmtaddr != NULLCHAR) {
- tprintf (showremote, (*ifp->iftype->format) (tmp, ifp->rmtaddr));
- #ifdef AXIP
- tprintf (showremoteIP, inet_ntoa (axipaddr[ifp->dev]));
- #endif
- }
- }
- #ifdef NETROM
- else if (ifp == Nr_iface)
- tprintf (" Alias %s\n", Nralias);
- #endif
- else
- #endif
- tputc ('\n');
- }
- }
- tprintf (showflags, ifp->flags, ifp->trace, ifp->netmask, inet_ntoa (ifp->broadcast));
- if (ifp->forw != NULLIF)
- tprintf (showforw, ifp->forw->name);
- #ifdef RXECHO
- if (ifp->rxecho != NULLIF)
- tprintf (showrxecho, ifp->rxecho->name);
- #endif
- tprintf (showsent, ifp->ipsndcnt, ifp->rawsndcnt, tformat (secclock () - ifp->lastsent));
- tprintf (showrecv, ifp->iprecvcnt, ifp->rawrecvcnt, tformat (secclock () - ifp->lastrecv));
- if (ifp->descr != NULLCHAR)
- tprintf (showdescr, ifp->descr);
- }
-
-
-
- /* Command to detach an interface */
- int
- dodetach (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
- {
- register struct iface *ifp;
-
- if ((ifp = if_lookup (argv[1])) == NULLIF) {
- tprintf (Badinterface, argv[1]);
- return 1;
- }
- if (if_detach (ifp) == -1)
- tputs (detnope);
- return 0;
- }
-
-
-
- /* Detach a specified interface */
- int
- if_detach (register struct iface *ifp)
- {
- struct iface *iftmp;
- struct route *rp, *rptmp;
- int i, j;
- struct ax_route *axr, *axr1;
- struct arp_tab *ap, *ap1;
-
- #ifdef ENCAP
- if (ifp == &Loopback || ifp == &Encap)
- #else
- if (ifp == &Loopback)
- #endif
- return -1;
-
- #ifdef AX25
- /* Drop all ax25 routes that points to this interface */
- for (axr = Ax_routes; axr != NULLAXR; axr = axr1) {
- axr1 = axr->next; /* Save the next pointer */
- if (axr->iface == ifp)
- (void) ax_drop (axr->target, ifp, AX_NONSETUP);
- /* axr will be undefined after ax_drop() */
- }
- #endif
-
- /* Drop all ARP's that point to this interface */
- for (i = 0; i < HASHMOD; ++i)
- for (ap = Arp_tab[i]; ap != NULLARP; ap = ap1) {
- ap1 = ap->next; /* Save the next pointer */
- if (ap->iface == ifp)
- arp_drop (ap);
- /* ap will be undefined after arp_drop() */
- }
-
-
- /* Drop all routes that point to this interface */
- if (R_default.iface == ifp)
- (void) rt_drop (0L, 0);/* Drop default route */
-
- for (i = 0; i < HASHMOD; i++) {
- for (j = 0; j < 32; j++) {
- for (rp = Routes[j][i]; rp != NULLROUTE; rp = rptmp) {
- /* Save next pointer in case we delete this entry */
- rptmp = rp->next;
- if (rp->iface == ifp)
- (void) rt_drop (rp->target, rp->bits);
- }
- }
- }
- /* Unforward any other interfaces forwarding to this one */
- for (iftmp = Ifaces; iftmp != NULLIF; iftmp = iftmp->next) {
- if (iftmp->forw == ifp)
- iftmp->forw = NULLIF;
- #ifdef RXECHO
- if (iftmp->rxecho == ifp)
- iftmp->rxecho = NULLIF;
- #endif
- }
-
- /* Call device shutdown routine, if any */
- if (ifp->stop != NULLFP ((struct iface *)))
- (void) (*ifp->stop) (ifp);
-
- killproc (ifp->rxproc);
- killproc (ifp->txproc);
- killproc (ifp->supv);
-
- #ifdef NETROM
- /*make sure that the netrom interface is properly detached
- *fixed 11/15/91, Johan. K. Reinalda, WG7J/PA3DIS
- */
- if (strcmp (ifp->name, "netrom") == 0) {
- for (iftmp = Ifaces; iftmp; iftmp = iftmp->next)
- iftmp->flags &= ~IS_NR_IFACE; /* this 'resets' active interfaces */
- Nr_iface = NULLIF;
- }
- #endif
-
- /* Free allocated memory associated with this interface */
- if (ifp->name != NULLCHAR)
- free (ifp->name);
- if (ifp->hwaddr != NULLCHAR)
- free (ifp->hwaddr);
- if (ifp->ipcall != NULLCHAR)
- free (ifp->ipcall);
- free (ifp->tcp);
- #ifdef AX25
- if (ifp->ax25) {
- if (ifp->ax25->bctext)
- free (ifp->ax25->bctext);
- free (ifp->ax25);
- }
- #endif
- free (ifp->descr);
-
- /* Remove from interface list */
- if (ifp == Ifaces)
- Ifaces = ifp->next;
- else {
- /* Search for entry just before this one
- * (necessary because list is only singly-linked.)
- */
- for (iftmp = Ifaces; iftmp != NULLIF; iftmp = iftmp->next)
- if (iftmp->next == ifp)
- break;
- if (iftmp != NULLIF && iftmp->next == ifp)
- iftmp->next = ifp->next;
- }
- /* Finally free the structure itself */
- free ((char *) ifp);
- return 0;
- }
-
-
-
- /* Given the ascii name of an interface, return a pointer to the structure,
- * or NULLIF if it doesn't exist
- */
- struct iface *
- if_lookup (const char *name)
- {
- register struct iface *ifp;
-
- for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if (stricmp (ifp->name, name) == 0)
- break;
- return ifp;
- }
-
-
-
- /* Return iface pointer if 'addr' belongs to one of our interfaces,
- * NULLIF otherwise.
- * This is used to tell if an incoming IP datagram is for us, or if it
- * has to be routed.
- */
- struct iface *
- ismyaddr (uint32 addr)
- {
- register struct iface *ifp;
-
- for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if (addr == ifp->addr)
- break;
- return ifp;
- }
-
-
-
- /* Given a network mask, return the number of contiguous 1-bits starting
- * from the most significant bit.
- */
- int
- mask2width (uint32 mask)
- {
- int width, i;
-
- width = 0;
- for (i = 31; i >= 0; i--) {
- if (!(mask & (1L << i)))
- break;
- width++;
- }
- return width;
- }
-
-
-
- /* return buffer with name + comment */
- char *
- if_name (struct iface *ifp, const char *comment)
- {
- char *result = mallocw (strlen (ifp->name) + strlen (comment) + 1);
-
- strcpy (result, ifp->name);
- return strcat (result, comment);
- }
-
-
-
- /* Raw output routine that tosses all packets. Used by dialer, tip, etc */
- int
- bitbucket (struct iface *ifp OPTIONAL, struct mbuf *bp)
- {
- free_p (bp);
- return 0;
- }
-
-
-
- /* Set interface (or AX25) flags on 1 or all interfaces */
- int
- dosetflag (int argc, char *argv[], void *p OPTIONAL, int flagtoset, int AX25only)
- {
- struct iface *ifp;
-
- if (argc < 2) {
- for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if (ifp->flags & flagtoset)
- tprintf ("%s\n", ifp->name);
- } else {
- if ((argc == 3) && (strcmp (argv[1], "all") == 0)) {
- for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
- if (!AX25only || ifp->type == CL_AX25) {
- if (strcmp (argv[2], "on") == 0)
- ifp->flags |= flagtoset;
- else if (strcmp (argv[2], "off") == 0)
- ifp->flags &= ~flagtoset; /*lint !e502 */
- else {
- tputs ("Please use on or off.\n");
- return 0;
- }
- }
- return 0;
- } else if ((ifp = if_lookup (argv[1])) == NULLIF) {
- tprintf (Badinterface, argv[1]);
- return 1;
- }
- if (AX25only && ifp->type != CL_AX25) {
- tputs ("not an AX.25 interface\n");
- return -1;
- }
- if (argc != 3)
- ifp->flags ^= flagtoset;
- else {
- if (strcmp (argv[2], "on") == 0)
- ifp->flags |= flagtoset;
- else if (strcmp (argv[2], "off") == 0)
- ifp->flags &= ~flagtoset; /*lint !e502 */
- else
- ifp->flags ^= flagtoset;
- }
- }
- return 0;
- }
-
-
- /* attach a dummy interface. no parms for now. */
- int
- dummy_attach (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- struct iface *dummy;
- uint32 n;
-
- if ((n = resolve (argv[2])) == 0) {
- tprintf (Badhost, argv[2]);
- return 1;
- }
-
- dummy = (struct iface *) callocw (1, sizeof (struct iface));
-
- dummy->addr = n;
- dummy->iface_metric = 1;
-
- /* The strdup is needed to keep the detach routine happy (it'll
- * free the allocated memory)
- */
- dummy->name = strdup (argv[1]);
- dummy->hwaddr = mallocw (AXALEN);
- memcpy (dummy->hwaddr, Mycall, AXALEN);
-
- dummy->mtu = MAXINT16;
- (void) setencap (dummy, "None");
- dummy->next = Ifaces;
- Ifaces = dummy;
-
- return 0;
- }
-
-
-
-